
#include <string.h>
#include <stdio.h>
#include "../Config.h"
#include "PngTexture.h"

// Initializes the class
PngTexture::PngTexture() {
    nChannels = 0;
    nBPP = 0;
}

// Finalizes the class
PngTexture::~PngTexture()	{
}

unsigned int PngTexture::getWidth() {
	return width;
}

unsigned int PngTexture::getHeight() {
	return height;
}


int PngTexture::clear() {
    for(int i = 0; i < (int)getHeight(); i++) {
        memset(pic[i], 0, getHeight());
    }

    return 0;
}

int PngTexture::load(string name) {
	unsigned char header[8];
	strcpy(this->filename, name.c_str());	

    FILE *fp = fopen(filename, "rb");
    if (!fp) {

        cerr << "ERROR: PngTexture: could not open file!\n" << endl;
        return 1;
    }
   
   // testa arquivo
    fread(header, 1, 8, fp);
    if (png_sig_cmp(header, 0, 8)) {
        cerr << ">> TEXTURE: PNG: Not a valid PNG file" << endl;
        return 1;
    }
    
    // cabeçalhos
    png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
    
    info_ptr = png_create_info_struct(png_ptr);
    if (!info_ptr) {
        cerr << ">> TEXTURE: PNG: Couldn't create info structure" << endl;
        png_destroy_read_struct(&png_ptr,(png_infopp)NULL, (png_infopp)NULL);
        return 1;
    }
    
    end_info = png_create_info_struct(png_ptr);
    if (!end_info) {
        cerr << ">> TEXTURE: PNG: Couldn't create end info structure" << endl;
        png_destroy_read_struct(&png_ptr, &info_ptr,(png_infopp)NULL);
        return 1;
    }

    // IO
    if (png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_GRAY)
      png_set_gray_1_2_4_to_8(png_ptr);

    png_init_io(png_ptr, fp);
    png_set_sig_bytes(png_ptr, 8);
    png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
    
    // Lendo arquivo
    pic = (png_bytep *)png_get_rows(png_ptr, info_ptr);
    
    fclose(fp); 
    
    width = png_get_image_width(png_ptr, info_ptr);
    height = png_get_image_height(png_ptr, info_ptr);
    nChannels = png_get_channels(png_ptr, info_ptr);
    nBPP = info_ptr->pixel_depth;
    
    return 0;
}

int PngTexture::write(string output) {
    FILE *fp = fopen(output.c_str(), "wb");
    if(!fp) {
        cerr << ">> TEXTURE: PNG: Couldn't open file to write" << endl;
        return 1;
    }
    
    png_structp png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,(png_voidp)NULL,NULL,NULL);
    if(!png_ptr) {
        cerr << ">> TEXTURE: PNG: Couldn't create write structure" << endl;
        return 1;
    }
    
    png_init_io(png_ptr, fp);
    png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL);
    fclose(fp);
    	
    return 0;
}


// copy the image to the buffer
bool PngTexture::CopyToBuffer(unsigned char *pbBuffer) {

  //aux vars
  int nCount, nIdx;

  if (!png_ptr)
    return false;

  nIdx = 0;
  for (nCount = 0; nCount < (int)height; nCount++) {

    nIdx = nCount * width * nChannels;
    memcpy(&pbBuffer[nIdx], pic[nCount], width * nChannels);
  }

  return true;
}

